package com.honeybee.cloud.framework.common.response;

import com.alibaba.fastjson.JSONObject;
import com.honeybee.cloud.framework.base.exception.ExceptionEnum;
import com.honeybee.cloud.framework.base.exception.business.BaseBizException;
import com.honeybee.cloud.framework.common.enums.ResponseEnum;
import lombok.Data;

import javax.validation.ConstraintViolationException;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.ZoneOffset;

/**
 * @Description 请求返回结果集
 * @Author cheng
 * @Create 2018-12-08
 * @Since 1.0.0
 */
@Data
@SuppressWarnings("unchecked")
public class ResponseEntity<T> implements Serializable {

    /**
     * 获取调用返回值
     */

    private T data;
    /**
     * 状态码 0成功 其他
     */
    private Integer code;
    /**
     * 子状态码 0成功 其他
     */
    private Integer subCode;

    /**
     * 子状态码说明
     */
    private String subMessage;

    private Boolean success;

    /**
     * 异常信息
     */
    private String message;
    /**
     * 时间戳
     */
    private Long timestamp;

    public ResponseEntity() {
    }

    public ResponseEntity(Integer parentCode, Integer subCode, String message, String subMessage) {
        this.code = parentCode;
        this.subCode = subCode;
        this.message = message;
        this.subMessage = subMessage;
        this.timestamp = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
    }

    public ResponseEntity(Integer parentCode, String message) {
        this(parentCode, null, message, null);
        this.timestamp = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
    }

    public static ResponseEntity ok() {
        ResponseEntity result = new ResponseEntity();
        result.setSuccess(true);
        result.setData(null);
        result.setMessage(ResponseEnum.SUCCESS.value);
        result.setTimestamp(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
        return result;
    }

    public static ResponseEntity ok(Object data) {
        ResponseEntity result = new ResponseEntity();
        result.setData(data);
        result.setSuccess(true);
        result.setMessage(ResponseEnum.SUCCESS.value);
        result.setTimestamp(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
        return result;
    }

    public static ResponseEntity error() {
        ResponseEntity result = new ResponseEntity();
        result.setSuccess(false);
        result.setData(null);
        result.setMessage(ResponseEnum.FAIL.value);
        result.setTimestamp(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
        return result;
    }

    public static ResponseEntity error(String msg) {
        ResponseEntity result = new ResponseEntity();
        result.setSuccess(false);
        result.setData(null);
        result.setMessage(msg);
        result.setTimestamp(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
        return result;
    }

    public static ResponseEntity error(BaseBizException ex) {
        ResponseEntity result = new ResponseEntity(ex.getParentCode(), ex.getSubCode(), ex.getMsg(), ex.getSubMessage());
        result.setSuccess(false);
        result.setMessage(ex.getMessage());
        result.setData(ex.getData());
        result.setSubCode(ex.getSubCode());
        return result;
    }

    public static ResponseEntity error(ConstraintViolationException ex) {
        ResponseEntity result = new ResponseEntity(ExceptionEnum.VALIDATION_EXCEPTION.getCode(), ex.getMessage());
        result.setSuccess(false);
        result.setData(null);
        return result;
    }

    public static ResponseEntity error(Exception ex) {
        ResponseEntity result = new ResponseEntity(ExceptionEnum.SYSTEM.getCode(), ex.getMessage());
        result.setSuccess(false);
        result.setData(null);
        return result;
    }

    public static ResponseEntity error(Integer parentCode, Integer subCode, String message, String subMessage) {
        ResponseEntity result = new ResponseEntity(parentCode, subCode, message, subMessage);
        result.setSuccess(false);
        result.setData(null);
        return result;
    }

    public static ResponseEntity error(Integer parentCode, String message, String subMessage) {
        return error(parentCode, null, message, subMessage);
    }

    @Override
    public String toString() {
        return JSONObject.toJSONString(this);
    }

}
